;;;; -*- Mode: Lisp; Package: dreaming-tree; -*-

(in-package :dreaming-tree)

;;;; Drawing Geometric Primitives ;;;;

(defmethod draw ((g geometry))
  ;; Set global state?
  (if (slot-boundp g 'vao)
      (with-model-transformation g
	(gllib::draw-vertex-list (slot-value g 'vao)))
      (draw-elements g)))

(defmethod draw-elements ((obj trimesh))
  (let* ((m (transformation obj))
	 (pv (m* (projection-matrix (camera (view obj)))
		 (view-matrix (camera (view obj)))))
	 (world-mvp-matrix (m* pv m)))
    (ccl:rlet ((zoffset :<GL>uint))
      (setf (ccl:%get-unsigned-byte zoffset) 0)
      (with-slots (v vid c cid n nid i iid tc tcid) obj
	;;
	(lib.gl::use-shader 'flat :uniforms world-mvp-matrix)
	;; Draw vertices
	(when (or (slot-boundp obj 'v) vid)
	  (format t "About to draw vertices.~%")
	  (gl:enable-client-state :vertex-array)
	  (if vid
	      (progn
		(gl:bind-buffer :array-buffer-arb vid)
		(%gl:vertex-pointer 3 (map-lisp-type-to-gl (element-type v)) 0 zoffset))
	      (%gl:vertex-pointer 3 (map-lisp-type-to-gl (element-type v)) 0 (get-pointer v)))
	  ;; (when (or (slot-boundp obj 'c) cid)
	  ;; 	(format t "About to draw colors.~%")
	  ;; 	(glEnableClientState GL_COLOR_ARRAY)
	  ;; 	(if cid
	  ;; 	    (progn
	  ;; 	      (glBindBufferARB GL_ARRAY_BUFFER_ARB cid)
	  ;; 	      (glColorPointer 3 (map-lisp-type-to-gl (element-type c)) 0 zoffset))
	  ;; 	    (glColorPointer 3 (map-lisp-type-to-gl (element-type c)) 0 (get-pointer c))))
	  ;; (when (or (slot-boundp obj 'n) nid)
	  ;; 	(format t "About to draw normals.~%")
	  ;; 	(glEnableClientState GL_NORMAL_ARRAY)
	  ;; 	(if nid
	  ;; 	    (progn
	  ;; 	      (glBindBufferARB GL_ARRAY_BUFFER_ARB nid)
	  ;; 	      (glNormalPointer (map-lisp-type-to-gl (element-type n)) 0 zoffset))
	  ;; 	    (glNormalPointer (map-lisp-type-to-gl (element-type n)) 0 (get-pointer n))))
	  ;; (when (or (slot-boundp obj 'tc) tcid)
	  ;; 	(format t "About to draw texture coordinates.~%")
	  ;; 	(glEnableClientState GL_TEXTURE_COORD_ARRAY)
	  ;; 	(if tcid
	  ;; 	    (progn
	  ;; 	      (glBindBufferARB GL_ARRAY_BUFFER_ARB nid)
	  ;; 	      (glTexCoordPointer 3 (map-lisp-type-to-gl (element-type tc)) 0 zoffset))
	  ;; 	    (glTexCoordPointer 2 (map-lisp-type-to-gl (element-type tc)) 0 (get-pointer tc))))
	  (format t "About to put it al together!~%"))
	(if iid
	    (progn
	      (gl:bind-buffer :element-array-buffer iid)
	      (gl:draw-elements :triangles nil :count (element-count i) :offset zoffset))
	    (gl:draw-elements :triangles (get-pointer i) :count (element-count i)))
	;;(glDrawArrays GL_POINTS 0 (lib.gl::element-count v))
	(gl:disable-client-state :texture-coord-array)
	(gl:disable-client-state :normal-array)
	(gl:disable-client-state :color-array)
	(gl:disable-client-state :vertex-array)))))

(defshader :vertex "330" :flat ((:in (vec4 vertex))
			       (:uniform (mat4 mvp-matrix)))
  (defun :void main ()
	 (setq gl-position (* mvp-matrix vertex))))

(defshader :fragment "330" :flat ((:in (vec4 color-value))
			       (:out (vec4 frag-color)))
  (defun :void main ()
	 (setq frag-color color-value)))
